﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using SarkothFarmer.ClassSpecifics;
using SarkothFarmer.Settings;
using Zeta;
using Zeta.Common;
using Zeta.CommonBot;
using Zeta.Internals.Actors;
using Zeta.Internals.SNO;

namespace SarkothFarmer.Helpers
{
    class StateManager
    {
        private bool cellar;
        public bool Cellar
        {
            get { return cellar; }
        }

        public State CurrentState;
        private ActorClass currentClass;
        public ActorClass CurrentClass
        {
            get { return currentClass; }
        }
        private Common character;
        public Common Character
        {
            get { return character; }
        }
        public enum State
        {
            Wait = 0,
            Scout = 1,
            Cellar = 2,
            Loot = 3,
            Done = 4,
            ForceLeave = 5
        }

        private Stats stats;
        public Stats GetStats
        {
            get { return stats; }
        }
        private Stopwatch timer = new Stopwatch();
        private bool moved;

        // Constructor
        public StateManager(ActorClass charClass)
        {
            currentClass = charClass;
            CurrentState = State.Scout;

            switch (charClass)
            {
                case ActorClass.Monk:
                    Logger.WriteVerbose("Initializing Monk procedures.");
                    character = new Monk();
                    break;
                case ActorClass.Barbarian:
                    Logger.WriteVerbose("Initializing Barbarian procedures.");
                    character = new Barbarian();
                    break;
                case ActorClass.WitchDoctor:
                    Logger.WriteVerbose("Initializing Witch Doctor procedures.");
                    character = new WitchDoctor();
                    break;
                case ActorClass.DemonHunter:
                    Logger.WriteVerbose("Initializing Demon Hunter procedures.");
                    character = new DemonHunter();
                    break;
                case ActorClass.Wizard:
                    Logger.WriteVerbose("Initializing Wizard procedures.");
                    character = new Wizard();
                    break;
                default:
                    Logger.WriteVerbose("Initializing Common procedures.");
                    character = new Common();
                    break;
            }
            stats = new Stats(this);
        }

        public void RunState()
        {
            switch (CurrentState)
            {
                case State.Wait:
                    StateWait();
                    break;
                case State.Scout:
                    StateScout();
                    break;
                case State.Cellar:
                    StateCellar();
                    break;
                case State.Loot:
                    StateLoot();
                    break;
                case State.Done:
                    StateDone();
                    break;
                case State.ForceLeave:
                    StateForceLeave();
                    break;
            }
        }
        public void ResetState()
        {
            CurrentState = State.Scout;
            moved = false;
        }
        private bool DemonHunterCellar()
        {
            if (PowerManager.CanCast(SNOPower.DemonHunter_Preparation))
                Common.UsePowerSelf(SNOPower.DemonHunter_Preparation);
            if (!moved && ZetaDia.Me.Position.Distance(Objects.HotspotSarkoth) > 15)
            {
                character.MoveTo(Objects.HotspotSarkoth);
                return false;
            }
            if (!moved && ZetaDia.Me.Position.Distance(Objects.HotspotSarkoth) <= 15)
            {
                moved = true;
                return false;
            }
            if (moved && ZetaDia.Me.Position.Distance(Objects.hotspotSarkothDoor) > 15)
            {
                character.FastMoveTo(Objects.hotspotSarkothDoor);
                return false;
            }
            return true;

        }
        private void StateWait()
        {
            if (!timer.IsRunning)
            {
                Logger.WriteVerbose("Starting timer");
                timer.Start();
            }
            if (timer.IsRunning && timer.ElapsedMilliseconds >= 0)
            {
                Logger.WriteVerbose("Resetting timer");
                CurrentState++;
                Logger.WriteVerbose("Switched state to {0}", CurrentState);
                timer.Reset();
            }
        }
        private void StateScout()
        {
            Composites.KillMonsters = false;
            if (!Composites.IsNear(Objects.HotspotScout))
            {
                character.FastMoveTo(Objects.HotspotScout);
            }
            else
            {
                ZetaDia.Actors.Update();
                if (Objects.DankCellar != null)
                {
                    CurrentState++;
                    cellar = true;
                    Logger.Write("Found Cellar! :)");
                }
                else
                {
                    CurrentState = State.Done;
                    Logger.WriteVerbose("Switched state to {0}", CurrentState);
                    cellar = false;
                    Logger.Write("No Cellar! :(");
                }
            }
        }
        private void StateCellar()
        {
            Composites.KillRadius = 100;
            Composites.LootRadius = 100;
            // In world - not inside cellar
            if (ZetaDia.Me.WorldDynamicId == 1999503360)
            {
                Common.UsePowerSelf(SNOPower.DemonHunter_Preparation);
                if (Composites.IsNear(Objects.HotspotCellarPortal))
                {
                    Objects.DankCellar.Interact();
                }
                else
                {
                    character.FastMoveTo(Objects.HotspotCellarPortal);
                }
            }
            // Inside cellar
            if (ZetaDia.Me.WorldDynamicId == 1999568897)
            {
                if (ZetaDia.Me.ActorClass == ActorClass.DemonHunter)
                {
                    if (DemonHunterCellar())
                    {
                        character.PreCombat();
                        CurrentState++;
                        Logger.WriteVerbose("Switched state to {0}", CurrentState);
                    }
                }
                else if (!Composites.IsNear(Objects.HotspotSarkoth))
                {
                    switch (Main.settingsWrapper.FastCellar)
                    {
                        case SettingsWrapper.TrueFalseDefault.True:
                            character.FastMoveTo(Objects.HotspotSarkoth);
                            break;
                        case SettingsWrapper.TrueFalseDefault.False:
                            character.MoveTo(Objects.HotspotSarkoth);
                            break;
                        case SettingsWrapper.TrueFalseDefault.Default:
                            switch (currentClass)
                            {
                                case ActorClass.Barbarian:
                                    character.FastMoveTo(Objects.HotspotSarkoth);
                                    break;
                                case ActorClass.WitchDoctor:
                                    character.FastMoveTo(Objects.HotspotSarkoth);
                                    break;
                                case ActorClass.Monk:
                                    character.MoveTo(Objects.HotspotSarkoth);
                                    break;
                                case ActorClass.Wizard:
                                    character.MoveTo(Objects.HotspotSarkoth);
                                    break;
                            }
                            break;
                    }
                    character.MoveTo(Objects.HotspotSarkoth);
                }
                else
                {
                    character.PreCombat();
                    CurrentState++;
                    Logger.WriteVerbose("Switched state to {0}", CurrentState);
                }
            }
        }
        private void StateLoot()
        {
            if (character.LootItems(Objects.Loots))
            {
                return;
            }
            if (character.LootGold(Objects.Gold))
            {
                return;
            }
            // If done looting - go to next state
            if (Composites.IsCleared)
            {
                CurrentState = State.Done;
                Logger.WriteVerbose("Switched state to {0}", CurrentState);
            }
        }
        private void StateDone()
        {
            // If some loot drops later, go back to looting
            if (Composites.InCellar && !Composites.IsCleared)
            {
                CurrentState = State.Loot;
                Logger.WriteVerbose("Switched state to {0}", CurrentState);
                return;
            }
            ZetaDia.Actors.Update();
            if (ZetaDia.Me.IsDead || ZetaDia.Me.HitpointsCurrentPct == 0)
            {
                ZetaDia.Service.Games.LeaveGame();
            }
            else if (!ZetaDia.Me.IsInTown)
                character.UseTP();
        }
        private void StateForceLeave()
        {
            ZetaDia.Actors.Update();
            if (ZetaDia.Me.IsDead || ZetaDia.Me.HitpointsCurrentPct == 0)
            {
                ZetaDia.Service.Games.LeaveGame();
            }
            else if (!ZetaDia.Me.IsInTown)
                character.UseTP();
        }

    }
}
